﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

using com.vs.General;
using com.vs.DataAccess;
using com.vs.DataAccess.DO;
using com.vs.Inventory.BL;
using com.vs.Receiving.BL;
using com.vs.General.BL;

namespace com.vs.Task.BL
{
    public class TaskExecutionHelper
    {
        #region ConfirmTask
        /// <summary>
        /// 确认任务。此方法不适用于RF
        /// </summary>
        /// <param name="sess"></param>
        /// <param name="tcDS"></param>
        /// <returns></returns>
        public string ConfirmTask(Session sess, int iTaskNum)
        {
            List<TaskDetailDO> ltTskDtl = null;
            TaskConfirmDS tcDS = null;
            StringBuilder sbErr = null;
            string stErr = null;

            try
            {
                ltTskDtl = TaskDetailDO.GetListByColumn(sess, "INTERNAL_TASK_NUM", iTaskNum);
                if (ltTskDtl == null || ltTskDtl.Count < 1)
                    return MessageManager.MSG_TSK_001; //任务明细未找到

                sbErr = new StringBuilder();
                foreach (TaskDetailDO tdDO in ltTskDtl)
                {
                    tcDS = new TaskConfirmDS();
                    tcDS.ACTUAL_FROM_LOC = tdDO.CURRENT_LOC;
                    tcDS.ACTUAL_FROM_LPN = tdDO.CURRENT_LPN;
                    tcDS.ACTUAL_TO_LOC = tdDO.TO_LOC;
                    if (LocationManager.DoseLocTrackLPN(sess, tdDO.WAREHOUSE, tdDO.TO_LOC))
                        tcDS.ACTUAL_TO_LPN = tdDO.CURRENT_LPN;
                    tcDS.CONFIRM_USER = sess.User;
                    tcDS.CONFIRM_QTY = tdDO.FROM_QTY;
                    tcDS.INTERNAL_TASK_LINE_NUM = tdDO.INTERNAL_TASK_LINE_NUM;
                    tcDS.QUANTITY_UM = tdDO.QUANTITY_UM;

                    stErr = this.ConfirmTask(sess, tcDS);
                    if (!StringManager.IsEmpty(stErr))
                        sbErr.AppendLine(stErr);
                }
                if (StringManager.IsEmpty(sbErr))
                    return null;
                else
                    return sbErr.ToString();
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
        }

        public string ConfirmTask(Session sess, TaskConfirmDS tcDS)
        {
            TaskDetailDO tdDO = null;
            InventoryChangeDS invChgDS = null;
            List<InventoryChangeDS> arInvChgDS = null;
            InventoryHelper invMgr = null;
            Dictionary<string, object> dcValue = null;
            TransactionHistoryDO thDO = null;
            string stErr = null;
            LocationManager locMgr = null;

            int iTaskLnNum = tcDS.INTERNAL_TASK_LINE_NUM;

            try
            {
                #region 获取任务行对象
                tdDO = TaskDetailDO.GetModelByPK(sess, iTaskLnNum);
                if (tdDO == null)
                {
                    //错误：工作未找到
                    return MessageManager.MSG_TSK_001;
                }
                #endregion

                #region 校验任务确认的参数
                stErr = this.validateWorkConfirm(sess, tdDO, tcDS);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;
                #endregion

                dcValue = new Dictionary<string, object>();

                if (!tdDO.INTERNAL_TASK_TYPE.StartsWith("*")) //*开始的工作类型表示此任务不需要调整库存，直接关闭即可。
                {

                    arInvChgDS = new List<InventoryChangeDS>();

                    #region 扣减原库位库存
                    invChgDS = new InventoryChangeDS();
                    invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                    invChgDS.COMPANY = tdDO.COMPANY;
                    invChgDS.LOCATION = tdDO.FROM_LOC;
                    invChgDS.LPN = tdDO.FROM_LPN;
                    invChgDS.ITEM = tdDO.ITEM;
                    invChgDS.QUANTITY = tcDS.CONFIRM_QTY;
                    invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                    invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                    invChgDS.INVENTORY_STS = tdDO.INVENTORY_STS;
                    invChgDS.OP_ONHANDQTY = "-";
                    invChgDS.OP_INTRANQTY = "";
                    invChgDS.OP_ALLOCQTY = "-";

                    arInvChgDS.Add(invChgDS);
                    #endregion
                    
                    #region 增加目标库位上实际put away的LPN的库存
                    //如果实际put away的LPN与源LPN不同，那么需要先做override，这里不考虑
                    //如果目标库位不track LPN，设置TO_LPN为空
                    locMgr = new LocationManager();
                    if (!LocationManager.DoseLocTrackLPN(sess, tdDO.WAREHOUSE, tdDO.TO_LOC))
                    {
                        tcDS.ACTUAL_TO_LPN = null;
                    }

                    invChgDS = new InventoryChangeDS();
                    invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                    invChgDS.COMPANY = tdDO.COMPANY;
                    invChgDS.ITEM = tdDO.ITEM;
                    invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                    invChgDS.INVENTORY_STS = tdDO.INVENTORY_STS;
                    invChgDS.QUANTITY = tcDS.CONFIRM_QTY;
                    invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                    invChgDS.LOCATION = tcDS.ACTUAL_TO_LOC;
                    invChgDS.LPN = tcDS.ACTUAL_TO_LPN;
                    invChgDS.OP_ONHANDQTY = "+";
                    invChgDS.OP_INTRANQTY = "-";
                    invChgDS.OP_ALLOCQTY = "";

                    arInvChgDS.Add(invChgDS);
                    #endregion

                    #region 调整库存
                    invMgr = new InventoryHelper();
                    stErr = invMgr.AdjustInventory(sess, arInvChgDS);
                    if (!StringManager.IsEmpty(stErr))
                    {
                        return stErr;
                    }
                    #endregion

                    #region 记录历史记录
                    foreach (InventoryChangeDS ds in arInvChgDS)
                    {
                        if (!StringManager.IsEmpty(ds.OP_ONHANDQTY))
                        {
                            thDO = new TransactionHistoryDO();
                            thDO.AFTER_ON_HAND_QTY = 0;
                            thDO.AFTER_STS = ds.INVENTORY_STS;
                            thDO.ATTRIBUTE_NUM = ds.ATTRIBUTE_NUM;
                            thDO.BEFORE_ON_HAND_QTY = 0;
                            thDO.BEFORE_STS = ds.INVENTORY_STS;
                            thDO.COMPANY = ds.COMPANY;
                            //thDO.DATE_TIME_STAMP = DateTime.Now;
                            thDO.DIRECTION = StringManager.Equals(ds.OP_ONHANDQTY, "+") ? Constants.stIN : Constants.stOUT;
                            thDO.ITEM = ds.ITEM;
                            thDO.ITEM_DESC = tdDO.ITEM_DESC;
                            thDO.LOCATION = ds.LOCATION;
                            thDO.LPN = ds.LPN;
                            thDO.QUANTITY = ds.QUANTITY;
                            thDO.QUANTITY_UM = ds.QUANTITY_UM;
                            thDO.REFERENCE_ID = tdDO.REFERENCE_ID;
                            thDO.REFERENCE_LINE_NUM = tdDO.REFERENCE_LINE_NUM;
                            thDO.REFERENCE_NUM = tdDO.REFERENCE_NUM;
                            thDO.REFERENCE_NUM_TYPE = tdDO.REFERENCE_NUM_TYPE;
                            thDO.TASK_ID = tdDO.TASK_ID;
                            thDO.TASK_TYPE = tdDO.TASK_TYPE;
                            thDO.TRANSACTION_TYPE = StringManager.Equals(ds.OP_ONHANDQTY, "+") ? Constants.stPUTAWAYCFM : Constants.stPICKCFM;
                            thDO.USER_STAMP = tdDO.ASSIGNED_USER;
                            thDO.WAREHOUSE = ds.WAREHOUSE;
                            //thDO.ZONE = 
                            thDO.Insert(sess);
                        }
                    }
                    #endregion

                }//任务确认+库存调整完毕
                else
                {
                    tdDO.FROM_QTY = 0;

                    #region 记录历史记录
                    thDO = new TransactionHistoryDO();
                    thDO.AFTER_ON_HAND_QTY = 0;
                    thDO.AFTER_STS = tdDO.INVENTORY_STS;
                    thDO.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                    thDO.BEFORE_ON_HAND_QTY = 0;
                    thDO.BEFORE_STS = tdDO.INVENTORY_STS;
                    thDO.COMPANY = tdDO.COMPANY;
                    //thDO.DATE_TIME_STAMP = DateTime.Now;
                    thDO.DIRECTION = Constants.stOUT;
                    thDO.ITEM = tdDO.ITEM;
                    thDO.ITEM_DESC = tdDO.ITEM_DESC;
                    thDO.LOCATION = tdDO.FROM_LOC;
                    thDO.LPN = tdDO.FROM_LPN;
                    thDO.QUANTITY = tdDO.TOTAL_QTY;
                    thDO.QUANTITY_UM = tdDO.QUANTITY_UM;
                    thDO.REFERENCE_ID = tdDO.REFERENCE_ID;
                    thDO.REFERENCE_LINE_NUM = tdDO.REFERENCE_LINE_NUM;
                    thDO.REFERENCE_NUM = tdDO.REFERENCE_NUM;
                    thDO.REFERENCE_NUM_TYPE = tdDO.REFERENCE_NUM_TYPE;
                    thDO.TASK_ID = tdDO.TASK_ID;
                    thDO.TASK_TYPE = tdDO.TASK_TYPE;
                    thDO.TRANSACTION_TYPE = Constants.stPICKCFM;
                    thDO.USER_STAMP = tdDO.ASSIGNED_USER;
                    thDO.WAREHOUSE = tdDO.WAREHOUSE;
                    //thDO.ZONE = 
                    thDO.Insert(sess);

                    thDO.DIRECTION = Constants.stIN;
                    thDO.LOCATION = tdDO.TO_LOC;
                    thDO.LPN = tdDO.TO_LPN;
                    thDO.TRANSACTION_TYPE = Constants.stPUTAWAYCFM;
                    thDO.Insert(sess);
                    #endregion
                }

                #region 更新任务数量和状态
                tdDO.FROM_QTY = tdDO.FROM_QTY - tcDS.CONFIRM_QTY;
                tdDO.CONFIRM_USER = sess.User;
                dcValue.Add("FROM_QTY", tdDO.FROM_QTY);
                dcValue.Add("CONFIRM_USER", sess.User);
                dcValue.Add("CONDITION", tdDO.FROM_QTY > 0 ? TaskConstants.INPROCESS : TaskConstants.CLOSED);
                tdDO.Update(sess, dcValue);
                #endregion

                #region 更新相关单据状态
                stErr = this.procAfterConfirm(sess, tdDO);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;
                #endregion

                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
                invChgDS = null;
                arInvChgDS = null;
            }
        }
        #endregion

        #region procAfterConfirm
        private string procAfterConfirm(Session sess, TaskDetailDO tdDO)
        {
            string stErr = null;
            ReceiptContManager rcMgr = null;
            ReceiptManager rpMgr = null;
            //ShipmentManager shMgr = null;

            try
            {
                #region 如果任务被完全执行，更新为完成状态；并更新Header状态
                //如果任务被完全执行，更新为完成状态；并更新Header状态
                if (tdDO.FROM_QTY <= 0 && tdDO.TO_QTY <= 0)
                {
                    stErr = this.CloseTaskLine(sess, tdDO);
                    if (!StringManager.IsEmpty(stErr))
                    {
                        return stErr;
                    }
                }
                #endregion

                #region 更新相关单据状态
                if (StringManager.Equals(tdDO.REFERENCE_NUM_TYPE, Constants.stRECEIPT) ||
                    StringManager.Equals(tdDO.REFERENCE_NUM_TYPE, Constants.stRECEIPT_NO_TASK))
                {
                    rcMgr = new ReceiptContManager();
                    stErr = rcMgr.UpdateContainerStatus(sess, tdDO.REFERENCE_CONT_NUM, StringManager.Equals(tdDO.CONDITION, TaskConstants.CLOSED) ? (int)Constants.InboundStatus.iCLOSED : (int)Constants.InboundStatus.iIN_PUTAWAY);
                    if (!StringManager.IsEmpty(stErr))
                        HistoryManager.SaveProcessHistory(sess, HistoryManager.ProcessType.iPutaway, HistoryManager.Condition.iFailed, stErr, tdDO.REFERENCE_ID, tdDO.FROM_LPN, null, null);
                    rpMgr = new ReceiptManager();
                    stErr = rpMgr.UpdateReceiptStatus(sess, tdDO.REFERENCE_NUM);
                    if (!StringManager.IsEmpty(stErr))
                        HistoryManager.SaveProcessHistory(sess, HistoryManager.ProcessType.iPutaway, HistoryManager.Condition.iFailed, stErr, tdDO.REFERENCE_ID, null, null, null);

                }
                else if (StringManager.Equals(tdDO.REFERENCE_NUM_TYPE, Constants.stSHIPMENT) ||
                    StringManager.Equals(tdDO.REFERENCE_NUM_TYPE, Constants.stSHIPMENT_NO_TASK))
                {
                    //shMgr = new ShipmentManager();
                    stErr = UpdateShipmentStatus(sess, tdDO.REFERENCE_NUM);
                }
                #endregion

                if (!StringManager.IsEmpty(stErr))
                    return stErr;
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
            }
        }

        private string UpdateShipmentStatus(Session sess, int iShpNum)
        {
            DataHelper helper = null;
            string stSQL = "SHP_UShipmentStatus";

            try
            {
                //更新行状态
                //更新整单状态
                helper = new DataHelper(sess);
                helper.Update(CommandType.StoredProcedure, stSQL, new IDataParameter[] { 
				            DataHelper.BuildParameter(sess, "@INTERNAL_SHIPMENT_NUM", iShpNum),
			            });
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
                if (helper != null)
                    helper.Dispose();
            }
        }

        #endregion

        #region ConfirmFromTask
        /// <summary>
        /// RF执行拣货任务：
        /// 1. 扣减拣货库位库存
        /// 2. 增加RF用户身上的库存
        /// 3. 目的库位库存保持不变
        /// 总体相当于将RF用户当做一个P&D库位
        /// </summary>
        /// <param name="sess"></param>
        /// <param name="tcDS"></param>
        /// <returns></returns>
        public string ConfirmFromTask(Session sess, TaskConfirmDS tcDS)
        {
            TaskDetailDO tdDO = null;
            //TaskHeaderDO thDO = null;
            InventoryChangeDS invChgDS = null;
            List<InventoryChangeDS> arInvChgDS = null;
            InventoryHelper invMgr = null;
            string stErr = null;
            Dictionary<string, object> dcValue = null;

            try
            {
                tdDO = TaskDetailDO.GetModelByPK(sess, tcDS.INTERNAL_TASK_LINE_NUM);
                if (tdDO == null)
                {
                    return MessageManager.MSG_TSK_001;//"任务明细未找到";
                }

                arInvChgDS = new List<InventoryChangeDS>();

                //扣减拣货位的库存
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                invChgDS.COMPANY = tdDO.COMPANY;
                invChgDS.LOCATION = tdDO.FROM_LOC;
                invChgDS.LPN = tdDO.FROM_LPN;
                invChgDS.ITEM = tdDO.ITEM;
                invChgDS.QUANTITY = tcDS.CONFIRM_QTY;
                invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                invChgDS.OP_ONHANDQTY = "-";
                invChgDS.OP_INTRANQTY = "";
                invChgDS.OP_ALLOCQTY = "-";

                arInvChgDS.Add(invChgDS);

                //增加目的库位（用户）上的库存
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                invChgDS.COMPANY = tdDO.COMPANY;
                invChgDS.LOCATION = tcDS.ACTUAL_TO_LOC; //必须存在以用户名命名的库位；
                //todo:建立用户时就应该建立这样一个库位
                invChgDS.LPN = tcDS.ACTUAL_TO_LPN;
                invChgDS.ITEM = tdDO.ITEM;
                invChgDS.QUANTITY = tcDS.CONFIRM_QTY;
                invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                invChgDS.OP_ONHANDQTY = "+";
                invChgDS.OP_INTRANQTY = "";
                invChgDS.OP_ALLOCQTY = "+";

                arInvChgDS.Add(invChgDS);

                invMgr = new InventoryHelper();
                stErr = invMgr.AdjustInventory(sess, arInvChgDS);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;

                dcValue = new Dictionary<string, object>();
                dcValue.Add("FROM_QTY", tdDO.FROM_QTY - tcDS.CONFIRM_QTY);
                dcValue.Add("TO_QTY", tdDO.TO_QTY + tcDS.CONFIRM_QTY);
                dcValue.Add("CONDITION", TaskConstants.INPROCESS);
                dcValue.Add("ASSIGNED_USER", tcDS.CONFIRM_USER);//将任务分配给执行用户，其余用户不能执行
                dcValue.Add("CURRENT_LOC", tcDS.ACTUAL_TO_LOC);
                dcValue.Add("CURRENT_LPN", tcDS.ACTUAL_TO_LPN);
                tdDO.Update(sess, dcValue);

                //更新任务头部+单据状态
                stErr = this.procAfterConfirm(sess, tdDO);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;
                stErr = this.procAfterConfirm(sess, tdDO);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;

                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
        }
        #endregion

        #region ConfirmToTask
        /// <summary>
        /// RF执行放货任务：
        /// 1. 扣减RF用户身上库存
        /// 2. 增加目的库位的库存
        /// </summary>
        /// <param name="sess"></param>
        /// <param name="tcDS"></param>
        /// <returns></returns>
        public string ConfirmToTask(Session sess, TaskConfirmDS tcDS)
        {
            TaskDetailDO tdDO = null;
            InventoryChangeDS invChgDS = null;
            List<InventoryChangeDS> arInvChgDS = null;
            InventoryHelper invMgr = null;
            string stErr = null;
            Dictionary<string, object> dcValue = null;

            try
            {
                tdDO = TaskDetailDO.GetModelByPK(sess, tcDS.INTERNAL_TASK_LINE_NUM);
                if (tdDO == null)
                {
                    return MessageManager.MSG_TSK_001;//"任务明细未找到";
                }

                arInvChgDS = new List<InventoryChangeDS>();

                //扣减当前库位的库存
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                invChgDS.COMPANY = tdDO.COMPANY;
                invChgDS.LOCATION = "-" + sess.User;
                invChgDS.LPN = tdDO.CURRENT_LPN;
                invChgDS.ITEM = tdDO.ITEM;
                invChgDS.QUANTITY = tcDS.CONFIRM_QTY;
                invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                invChgDS.OP_ONHANDQTY = "-";
                invChgDS.OP_INTRANQTY = "";
                invChgDS.OP_ALLOCQTY = "-";

                arInvChgDS.Add(invChgDS);

                //增加目的库位库存
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                invChgDS.COMPANY = tdDO.COMPANY;
                invChgDS.ITEM = tdDO.ITEM;
                invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                invChgDS.QUANTITY = tcDS.CONFIRM_QTY;
                invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                invChgDS.LOCATION = tcDS.ACTUAL_TO_LOC;
                invChgDS.LPN = tcDS.ACTUAL_TO_LPN;
                invChgDS.OP_ONHANDQTY = "+";
                invChgDS.OP_INTRANQTY = "";
                invChgDS.OP_ALLOCQTY = "";

                arInvChgDS.Add(invChgDS);

                invMgr = new InventoryHelper();
                stErr = invMgr.AdjustInventory(sess, arInvChgDS);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;

                tdDO.TO_QTY = tdDO.TO_QTY - tcDS.CONFIRM_QTY;
                if (tdDO.FROM_QTY == 0 && tdDO.TO_QTY == 0)
                    tdDO.CONDITION = Constants.stCLOSED;
                else
                    tdDO.CONDITION = Constants.stINPROCESS;

                dcValue = new Dictionary<string, object>();

                dcValue.Add("TO_QTY", tdDO.TO_QTY);
                dcValue.Add("CONDITION", tdDO.CONDITION);
                
                tdDO.Update(sess, dcValue);

                stErr = this.procAfterConfirm(sess, tdDO);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message; ;
            }
        }
        #endregion

        #region CloseTaskLine
        public string CloseTaskLine(Session sess, TaskDetailDO tdDO)
        {
            Dictionary<string, object> dcData = null;
            string stErr = null;

            try
            {

                dcData = new Dictionary<string, object>();

                if (tdDO.FROM_QTY == 0 && tdDO.TO_QTY == 0)
                {
                    dcData.Add("CONDITION", TaskConstants.CLOSED);
                    dcData.Add("FROM_QTY", 0);
                    dcData.Add("TO_QTY", 0);
                    stErr = tdDO.Update(sess, dcData);
                    tdDO.CONDITION = TaskConstants.CLOSED;
                    tdDO.FROM_QTY = 0;
                }
                else
                {
                    dcData.Add("CONDITION", TaskConstants.INPROCESS);
                    dcData.Add("FROM_QTY", tdDO.FROM_QTY);
                    dcData.Add("TO_QTY", tdDO.TO_QTY);
                    stErr = tdDO.Update(sess, dcData);
                    tdDO.CONDITION = TaskConstants.INPROCESS;
                }

                if (!StringManager.IsEmpty(stErr))
                    //throw new Exception();
                    HistoryManager.SaveProcessHistory(sess, HistoryManager.ProcessType.iPickAndPutaway, HistoryManager.Condition.iFailed, stErr, tdDO.TASK_ID, ""+tdDO.INTERNAL_TASK_LINE_NUM, null, null);
                return this.CloseTask(sess, tdDO.INTERNAL_TASK_NUM);
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
                dcData = null;
            }
        }
        #endregion

        #region CloseTask
        public string CloseTask(Session sess, int iTaskNum)
        {
            DataHelper helper = null;
            DataTable dt = null;
            int iSumOpenQty = 0;
            string stSQL = null;
            TaskHeaderDO thDO = null;
            Dictionary<string, object> dcData = null;
            
            try
            {
                stSQL = "SELECT SUM(FROM_QTY) + SUM(TO_QTY) FROM TASK_DETAIL WHERE INTERNAL_TASK_NUM = " + iTaskNum;
                helper = new DataHelper(sess);
                dt = helper.GetTable(CommandType.Text, stSQL);
                if (!DataManager.IsEmpty(dt))
                {
                    iSumOpenQty = DataManager.GetInt(dt.Rows[0], 0);

                    //如果剩余数量总和为零，则此任务已完全结束，可以关闭
                    thDO = new TaskHeaderDO();
                    thDO.INTERNAL_TASK_NUM = iTaskNum;
                    dcData = new Dictionary<string, object>();
                    if (iSumOpenQty <= 0)
                        dcData.Add("CONDITION", TaskConstants.CLOSED);
                    else
                        dcData.Add("CONDITION", TaskConstants.INPROCESS);

                    thDO.Update(sess, dcData);
                }
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000;
            }
            finally
            {
            }
        }
        #endregion

        #region GetTaskDetails
        public DataTable GetTaskDetails(Session sess, Dictionary<string, KeyValuePair<string, object>> dcCond)
        {
            return TaskDetailDO.GetTableByColumns(sess, DictionaryManager.ToList(dcCond), null);
        }
        #endregion

        #region CancelTaskDetail
        public string CancelTaskDetail(Session sess, int iTaskLnNum)
        {
            TaskDetailDO tskDtlDO = null;
            string stErr = null;
            InventoryChangeDS invChgDS;
            List<InventoryChangeDS> arInvChgDS = null;
            InventoryHelper ivMgr = null;
            string stOriginalSts = null;

            try
            {
                tskDtlDO = TaskDetailDO.GetModelByPK(sess, iTaskLnNum);
                if (null == tskDtlDO)
                    return MessageManager.MSG_TSK_001;

                stOriginalSts = tskDtlDO.CONDITION;
                tskDtlDO.CONDITION = TaskConstants.CANCELLED;
                stErr = tskDtlDO.Update(sess);

                if (!StringManager.IsEmpty(stErr))
                    return stErr;

                arInvChgDS = new List<InventoryChangeDS>();

                //创建InventoryChangeDS
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tskDtlDO.WAREHOUSE;
                invChgDS.COMPANY = tskDtlDO.COMPANY;
                invChgDS.ITEM = tskDtlDO.ITEM;
                invChgDS.ATTRIBUTE_NUM = tskDtlDO.ATTRIBUTE_NUM;
                invChgDS.QUANTITY = tskDtlDO.TOTAL_QTY - tskDtlDO.FROM_QTY;
                invChgDS.QUANTITY_UM = tskDtlDO.QUANTITY_UM;
                invChgDS.LOCATION = tskDtlDO.TO_LOC;
                invChgDS.LPN = tskDtlDO.TO_LPN;
                invChgDS.INVENTORY_STS = tskDtlDO.INVENTORY_STS;
                invChgDS.OP_ONHANDQTY = "-";
                invChgDS.OP_INTRANQTY = "";
                invChgDS.OP_ALLOCQTY = "-";

                arInvChgDS.Add(invChgDS);

                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tskDtlDO.WAREHOUSE;
                invChgDS.COMPANY = tskDtlDO.COMPANY;
                invChgDS.ITEM = tskDtlDO.ITEM;
                invChgDS.ATTRIBUTE_NUM = tskDtlDO.ATTRIBUTE_NUM;
                invChgDS.QUANTITY = tskDtlDO.TOTAL_QTY - tskDtlDO.FROM_QTY;
                invChgDS.QUANTITY_UM = tskDtlDO.QUANTITY_UM;
                invChgDS.LOCATION = tskDtlDO.FROM_LOC;
                invChgDS.LPN = tskDtlDO.FROM_LPN;
                invChgDS.INVENTORY_STS = tskDtlDO.INVENTORY_STS;
                invChgDS.OP_ONHANDQTY = "+";
                invChgDS.OP_INTRANQTY = "-";
                invChgDS.OP_ALLOCQTY = "";

                arInvChgDS.Add(invChgDS);

                //调整库存
                ivMgr = new InventoryHelper();
                stErr = ivMgr.AdjustInventory(sess, arInvChgDS);
                //调整库存失败，回滚工作状态变更
                if (!StringManager.IsEmpty(stErr))
                {
                    tskDtlDO.CONDITION = stOriginalSts;
                    stErr = tskDtlDO.Update(sess);
                    return stErr;
                }
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000;
            }
            finally
            {
                invChgDS = null;
                arInvChgDS = null;
                tskDtlDO = null;
                ivMgr = null;
            }
        }
        #endregion

        #region validateWorkConfirm
        private string validateWorkConfirm(Session sess, TaskDetailDO tdDO, TaskConfirmDS tcDS)
        {
            DataHelper helper = null;
            string stErr = null;

            try
            {
                helper = new DataHelper(sess);
                //todo:同时需要校验此任务在这个时刻是否已分配给其它用户
                stErr = helper.GetString(CommandType.StoredProcedure, "TSK_VConfirmTask", new IDataParameter[]{
                    DataHelper.BuildParameter(sess, "@INTERNAL_TASK_LINE_NUM", tdDO.INTERNAL_TASK_LINE_NUM),
                    DataHelper.BuildParameter(sess, "@ACTUAL_FROM_LOC", tcDS.ACTUAL_FROM_LOC),
                    DataHelper.BuildParameter(sess, "@ACTUAL_FROM_LPN", tcDS.ACTUAL_FROM_LPN),
                    DataHelper.BuildParameter(sess, "@ACTUAL_TO_LOC", tcDS.ACTUAL_TO_LPN),
                    DataHelper.BuildParameter(sess, "@ACTUAL_TO_LPN", tcDS.ACTUAL_TO_LPN),
                    DataHelper.BuildParameter(sess, "@CONFIRM_QTY", tcDS.CONFIRM_QTY)});
                return stErr;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + ": " + e.Message; ;
            }
        }
        #endregion

        #region SplitTaskDetail
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sess"></param>
        /// <param name="tdDO"></param>
        /// <param name="iQty"></param>
        /// <returns>返回被拆分出来的任务明细的内部号码</returns>
        public int SplitTaskDetail(Session sess, int iIntTskLnNum, int iQty, ref string stErr)
        {
            TaskDetailDO tdDO = null;

            tdDO = TaskDetailDO.GetModelByPK(sess, iIntTskLnNum);
            return this.SplitTaskDetail(sess, tdDO, iQty, ref stErr);
        }
        #endregion

        #region SplitTaskDetail
        public int SplitTaskDetail(Session sess, TaskDetailDO tdDO, int iQty, ref string stErr)
        {
            Dictionary<string, object> dcValue = null;

            try
            {
                if (iQty > tdDO.FROM_QTY)
                {
                    stErr = MessageManager.MSG_TSK_020; //拆分数量超出任务剩余数量";
                    return -1;
                }

                dcValue = new Dictionary<string, object>();
                dcValue.Add("TOTAL_QTY", tdDO.TOTAL_QTY - iQty);
                dcValue.Add("FROM_QTY", tdDO.FROM_QTY - iQty);

                if (tdDO.FROM_QTY - iQty == 0)
                {
                    dcValue.Add("CONDITION", TaskConstants.CLOSED);
                }
                tdDO.Update(sess, dcValue);

                tdDO.INTERNAL_TASK_LINE_NUM = 0;
                tdDO.TOTAL_QTY = iQty;
                tdDO.FROM_QTY = iQty;
                tdDO.CONDITION = TaskConstants.OPEN;
                tdDO.DATE_TIME_STAMP = System.DateTime.Now;
                tdDO.USER_STAMP = sess.User;
                return tdDO.Insert(sess);
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                stErr = MessageManager.MSG_GEN_000 + e.Message;
                return -1;
            }

        }
        #endregion

        #region OverridePickTask
        /// <summary>
        /// 不能只override部分数量
        /// 不能override已执行一半的任务，请先拆分任务
        /// </summary>
        /// <param name="sess"></param>
        /// <param name="iTaskNum"></param>
        /// <param name="stOverrideLoc"></param>
        /// <param name="stOverrideLPN"></param>
        /// <returns></returns>
        public string OverridePickTask(Session sess, int iTaskNum, string stOverrideLoc, string stOverrideLPN)
        {
            TaskDetailDO tdDO = null;
            InventoryManager invMgr = null;
            int iAvailableQty = 0;
            List<LocationInventoryDO> ltInv = null;
            LocationInventoryDO overrideInvDO = null;
            string stErr = null;

            try
            {
                //只有当当前库位等于原始库位时才允许做override pick， 其余时刻只能做任务接力
                //只有拣货或者补货才可以做override pick，上架、库存移动都不可以
                //override要修改库存分配记录，接力不需要

                #region 校验override条件
                tdDO = TaskDetailDO.GetModelByPK(sess, iTaskNum);
                if (tdDO ==  null)
                    return MessageManager.MSG_TSK_001; //任务明细未找到

                if (tdDO.INTERNAL_TASK_TYPE.StartsWith("*"))
                    return MessageManager.MSG_TSK_019; //该类型任务已经完成库存变动，不能覆盖
                
                if (!StringManager.Equals(tdDO.INTERNAL_TASK_TYPE, TaskConstants.SHIPMENT) &&
                    !StringManager.Equals(tdDO.INTERNAL_TASK_TYPE, TaskConstants.REPLENISHMENT))
                    return MessageManager.MSG_TSK_017;//只有拣货和补货可以做覆盖 

                if (!StringManager.Equals(tdDO.FROM_LOC, tdDO.CURRENT_LOC))
                    return MessageManager.MSG_TSK_014; //只有原始任务才可以覆盖

                if (StringManager.Equals(tdDO.FROM_LOC, stOverrideLoc) &&
                    StringManager.Equals(tdDO.FROM_LPN, stOverrideLPN))
                        return MessageManager.MSG_TSK_015; //必须覆盖到不同的库位或者LPN

                //if (iQty != tdDO.OPEN_QTY)
                //    return MessageManager.MSG_TSK_003;//确认数量超出剩余数量

                //TODO:是否允许override不一样的批号
                invMgr = new InventoryManager();
                ltInv = invMgr.GetInventory(sess, tdDO.WAREHOUSE, tdDO.COMPANY, tdDO.ITEM, stOverrideLoc, stOverrideLPN, tdDO.ATTRIBUTE_NUM, tdDO.INVENTORY_STS);
                bool bMatched = false;
                //在库存记录中寻找符合条件的记录
                foreach (LocationInventoryDO invDO in ltInv)
                {
                    iAvailableQty = invDO.ON_HAND_QTY + invDO.IN_TRANSIT_QTY - invDO.ALLOCATED_QTY;
                    if (iAvailableQty >= tdDO.FROM_QTY)
                    {
                        bMatched = true;
                        overrideInvDO = invDO;
                        break;
                    }
                }
                if (!bMatched)
                    return MessageManager.MSG_TSK_016; //库位上没有足够的数量";
                #endregion

                #region 恢复原库位的库存；扣减新库位的库存
                List<InventoryChangeDS> arInvChgDS;
                InventoryChangeDS invChgDS;
                InventoryHelper helper = null;
                arInvChgDS = new List<InventoryChangeDS>();

                //还原原分配库位的库存
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                invChgDS.COMPANY = tdDO.COMPANY;
                invChgDS.LOCATION = tdDO.FROM_LOC;
                invChgDS.LPN = tdDO.FROM_LPN;
                invChgDS.ITEM = tdDO.ITEM;
                invChgDS.QUANTITY = tdDO.FROM_QTY;
                invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                invChgDS.INVENTORY_STS = tdDO.INVENTORY_STS;
                invChgDS.OP_ONHANDQTY = "";
                invChgDS.OP_INTRANQTY = "";
                invChgDS.OP_ALLOCQTY = "-";

                arInvChgDS.Add(invChgDS);

                //扣减实际拣货库位的库存
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                invChgDS.COMPANY = tdDO.COMPANY;
                invChgDS.LOCATION = stOverrideLoc;
                invChgDS.LPN = stOverrideLPN;
                invChgDS.ITEM = tdDO.ITEM;
                invChgDS.QUANTITY = tdDO.FROM_QTY;
                invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                invChgDS.INVENTORY_STS = tdDO.INVENTORY_STS;
                invChgDS.OP_ONHANDQTY = "";
                invChgDS.OP_INTRANQTY = "";
                invChgDS.OP_ALLOCQTY = "+";

                arInvChgDS.Add(invChgDS);

                helper = new InventoryHelper();
                stErr = helper.AdjustInventory(sess, arInvChgDS);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;
                #endregion

                #region 更新任务
                Dictionary<string, object> dcValue = null;
                dcValue = new Dictionary<string, object>();
                dcValue.Add("FROM_LOC", stOverrideLoc);
                dcValue.Add("CURRENT_LOC", stOverrideLoc);
                dcValue.Add("FROM_LPN", stOverrideLPN);
                dcValue.Add("CURRENT_LPN", stOverrideLPN);
                tdDO.Update(sess, dcValue);
                #endregion

                #region 调整库存分配记录
                stErr = this.adjustShipAllocReq(sess, tdDO.REFERENCE_REQ_NUM, stOverrideLoc, stOverrideLPN, tdDO.ATTRIBUTE_NUM, tdDO.FROM_QTY);
                #endregion

                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
        }
        #endregion

        #region OverridePutawayTask
        public string OverridePutawayTask(Session sess, int iTaskNum, string stOverrideLoc, string stOverrideLPN)
        {
            TaskDetailDO tdDO = null;
            string stErr = null;

            try
            {
                //只有上架任务才可以覆盖putaway location

                #region 校验override条件
                tdDO = TaskDetailDO.GetModelByPK(sess, iTaskNum);
                if (tdDO == null)
                    return MessageManager.MSG_TSK_001; //任务明细未找到
                
                if (tdDO.INTERNAL_TASK_TYPE.StartsWith("*"))
                    return MessageManager.MSG_TSK_019; //该类型任务已经完成库存变动，不能覆盖

                if (!StringManager.Equals(tdDO.INTERNAL_TASK_TYPE, TaskConstants.RECEIPT))
                    return MessageManager.MSG_TSK_018;//只有上架任务才可以覆盖putaway location 

                if (StringManager.Equals(tdDO.TO_LOC, stOverrideLoc) &&
                    StringManager.Equals(tdDO.TO_LPN, stOverrideLPN))
                    return MessageManager.MSG_TSK_015; //必须覆盖到不同的库位或者LPN

                //目标库位是否记录LPN
                //目标库位是否允许混放货品
                //TODO:目标库位是否允许混放批号
                #endregion

                #region 恢复原库位的库存；增加新库位的库存
                List<InventoryChangeDS> arInvChgDS;
                InventoryChangeDS invChgDS;
                InventoryHelper helper = null;
                arInvChgDS = new List<InventoryChangeDS>();

                //扣除原目标库位的库存
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                invChgDS.COMPANY = tdDO.COMPANY;
                invChgDS.LOCATION = tdDO.TO_LOC;
                invChgDS.LPN = tdDO.TO_LPN;
                invChgDS.ITEM = tdDO.ITEM;
                invChgDS.QUANTITY = tdDO.FROM_QTY;
                invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                invChgDS.INVENTORY_STS = tdDO.INVENTORY_STS;
                invChgDS.OP_ONHANDQTY = "";
                invChgDS.OP_INTRANQTY = "-";
                invChgDS.OP_ALLOCQTY = "";

                arInvChgDS.Add(invChgDS);

                //增加覆盖的目标库位的库存
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                invChgDS.COMPANY = tdDO.COMPANY;
                invChgDS.LOCATION = stOverrideLoc;
                invChgDS.LPN = stOverrideLPN;
                invChgDS.ITEM = tdDO.ITEM;
                invChgDS.QUANTITY = tdDO.FROM_QTY;
                invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                invChgDS.INVENTORY_STS = tdDO.INVENTORY_STS;
                invChgDS.OP_ONHANDQTY = "";
                invChgDS.OP_INTRANQTY = "+";
                invChgDS.OP_ALLOCQTY = "";

                arInvChgDS.Add(invChgDS);

                helper = new InventoryHelper();
                stErr = helper.AdjustInventory(sess, arInvChgDS);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;
                #endregion

                #region 更新任务
                Dictionary<string, object> dcValue = null;
                dcValue = new Dictionary<string, object>();
                
                dcValue.Add("TO_LOC", stOverrideLoc);
                dcValue.Add("TO_LPN", stOverrideLPN);
                tdDO.Update(sess, dcValue);
                #endregion

                #region 更新收货托盘的目标库位
                ReceiptContainerDO rcDO = null;
                dcValue.Clear();
                //重要：如果上架后取消定位的时候，会需要这个信息
                rcDO = ReceiptContainerDO.GetModelByPK(sess, tdDO.REFERENCE_CONT_NUM);
                if (null == rcDO)
                {
                    //todo:记录历史
                }
                else
                {
                    dcValue = new Dictionary<string, object>();
                    dcValue.Add("TO_LOCATION", stOverrideLoc);
                    rcDO.Update(sess, dcValue);
                }
                #endregion

                #region 记录历史记录
                //todo:记录历史
                #endregion

                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
            }
        }
        #endregion

        #region OverridePickDrop
        public string OverridePickDrop(Session sess, int iTaskNum, string stOverrideLoc, string stOverrideLPN)
        {
            TaskDetailDO tdDO = null;
            string stErr = null;

            try
            {
                //只更新current_loc和状态

                #region 恢复原库位的库存；增加新库位的库存
                List<InventoryChangeDS> arInvChgDS;
                InventoryChangeDS invChgDS;
                InventoryHelper helper = null;
                arInvChgDS = new List<InventoryChangeDS>();

                //扣除原目标库位的库存
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                invChgDS.COMPANY = tdDO.COMPANY;
                invChgDS.LOCATION = tdDO.FROM_LOC;
                invChgDS.LPN = tdDO.FROM_LPN;
                invChgDS.ITEM = tdDO.ITEM;
                invChgDS.QUANTITY = tdDO.FROM_QTY;
                invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                invChgDS.INVENTORY_STS = tdDO.INVENTORY_STS;
                invChgDS.OP_ONHANDQTY = "";
                invChgDS.OP_INTRANQTY = "-";
                invChgDS.OP_ALLOCQTY = "";

                arInvChgDS.Add(invChgDS);

                //扣减实际拣货库位的库存
                invChgDS = new InventoryChangeDS();
                invChgDS.WAREHOUSE = tdDO.WAREHOUSE;
                invChgDS.COMPANY = tdDO.COMPANY;
                invChgDS.LOCATION = stOverrideLoc;
                invChgDS.LPN = stOverrideLPN;
                invChgDS.ITEM = tdDO.ITEM;
                invChgDS.QUANTITY = tdDO.FROM_QTY;
                invChgDS.QUANTITY_UM = tdDO.QUANTITY_UM;
                invChgDS.ATTRIBUTE_NUM = tdDO.ATTRIBUTE_NUM;
                invChgDS.INVENTORY_STS = tdDO.INVENTORY_STS;
                invChgDS.OP_ONHANDQTY = "";
                invChgDS.OP_INTRANQTY = "+";
                invChgDS.OP_ALLOCQTY = "";

                arInvChgDS.Add(invChgDS);

                helper = new InventoryHelper();
                stErr = helper.AdjustInventory(sess, arInvChgDS);
                if (!StringManager.IsEmpty(stErr))
                    return stErr;
                #endregion
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
        }
        #endregion

        #region adjustShipAllocReq
        private string adjustShipAllocReq(Session sess, int iAllocNum, string stLoc, string stLPN, int iAttrNum, int iQty)
        {
            DataHelper helper = null;
            try
            {
                helper = new DataHelper(sess);
                helper.Update(CommandType.StoredProcedure, "TSK_AdjustShipAllocReq", new IDataParameter[]{
                    DataHelper.BuildParameter(sess, "@INTERNAL_SHIP_ALLOC_NUM", iAllocNum),
                    DataHelper.BuildParameter(sess, "@FROM_LOC", stLoc),
                    DataHelper.BuildParameter(sess, "@FROM_LPN", stLPN),
                    DataHelper.BuildParameter(sess, "@ATTRIBUTE_NUM", iAttrNum),
                    DataHelper.BuildParameter(sess, "@QUANTITY", iQty)});
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
                if (helper != null)
                    helper.Dispose();
            }
        }
        #endregion

        #region adjustRecpLocReq
        private string adjustRecpLocReq(Session sess, int iLocNum, string stLoc, string stLPN, int iAttrNum, int iQty)
        {
            DataHelper helper = null;
            try
            {
                helper = new DataHelper(sess);
                helper.Update(CommandType.StoredProcedure, "TSK_AdjustRecpLocReq", new IDataParameter[]{
                    DataHelper.BuildParameter(sess, "@INTERNAL_REC_LOC_NUM", iLocNum),
                    DataHelper.BuildParameter(sess, "@TO_LOC", stLoc),
                    DataHelper.BuildParameter(sess, "@TO_LPN", stLPN),
                    DataHelper.BuildParameter(sess, "@ATTRIBUTE_NUM", iAttrNum),
                    DataHelper.BuildParameter(sess, "@QUANTITY", iQty)});
                return null;
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + e.Message;
            }
            finally
            {
                if (helper != null)
                    helper.Dispose();
            }
        }
        #endregion

        #region AssignToUser
        public string AssignToUser(Session sess, int iTaskNum, string stUser)
        {
            DataHelper helper = null;

            try
            {
                helper = new DataHelper(sess);
                return helper.GetString(CommandType.StoredProcedure, "TSK_AssignToUser", new IDataParameter[]{
                        DataHelper.BuildParameter(sess, "@INTERNAL_TASK_NUM", iTaskNum),
                        DataHelper.BuildParameter(sess, "@ASSIGNED_USER", stUser)});
            }
            catch (Exception e)
            {
                ExceptionManager.LogException(sess, e);
                return MessageManager.MSG_GEN_000 + ": " + e.Message;
            }
            finally
            {
                if (helper != null)
                helper.Dispose();
            }
        }
        #endregion
    }
}
